package com.htn.common.core.utils;

import com.alibaba.fastjson.JSONObject;
import com.htn.common.core.constant.SecurityConstants;
import com.htn.common.core.domain.LoginUserDto;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author shuang.kou
 * @description JWT工具类
 */
public class JwtTokenUtils {


	/**
	 * 生成足够的安全随机密钥，以适合符合规范的签名
	 */
	private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(SecurityConstants.JWT_SECRET_KEY.getBytes());

	public static String createToken(String username, String id, boolean isRememberMe) {
		long expiration = isRememberMe ? SecurityConstants.EXPIRATION_REMEMBER : SecurityConstants.EXPIRATION;
		final Date createdDate = new Date();
		final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);
		String tokenPrefix = Jwts.builder()
				.claim(SecurityConstants.ROLE_CLAIMS, String.join(",", new ArrayList<>()))
				.setHeaderParam("type", SecurityConstants.TOKEN_TYPE)
				.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
				.setId(id)
				.setIssuer("SnailClimb")
				.setIssuedAt(createdDate)
				.setSubject(username)
				.setExpiration(expirationDate)
				.compact();
		/**
		 * 添加 token 前缀 "Bearer "
		 */
		return SecurityConstants.TOKEN_PREFIX + tokenPrefix;
	}

	public static String getId(String token) {
		token = SecurityUtils.replaceTokenPrefix(token);
		Claims claims = getClaims(token);
		Object sub = claims.getSubject();
		return claims.getId();
	}

	private static Claims getClaims(String token) {
		if(StringUtils.isBlank(token) || "undefined".equals(token)){
			return new Claims() {
				@Override
				public String getIssuer() {
					return null;
				}

				@Override
				public Claims setIssuer(String s) {
					return null;
				}

				@Override
				public String getSubject() {
					return null;
				}

				@Override
				public Claims setSubject(String s) {
					return null;
				}

				@Override
				public String getAudience() {
					return null;
				}

				@Override
				public Claims setAudience(String s) {
					return null;
				}

				@Override
				public Date getExpiration() {
					return null;
				}

				@Override
				public Claims setExpiration(Date date) {
					return null;
				}

				@Override
				public Date getNotBefore() {
					return null;
				}

				@Override
				public Claims setNotBefore(Date date) {
					return null;
				}

				@Override
				public Date getIssuedAt() {
					return null;
				}

				@Override
				public Claims setIssuedAt(Date date) {
					return null;
				}

				@Override
				public String getId() {
					return null;
				}

				@Override
				public Claims setId(String s) {
					return null;
				}

				@Override
				public <T> T get(String s, Class<T> aClass) {
					return null;
				}

				@Override
				public int size() {
					return 0;
				}

				@Override
				public boolean isEmpty() {
					return false;
				}

				@Override
				public boolean containsKey(Object key) {
					return false;
				}

				@Override
				public boolean containsValue(Object value) {
					return false;
				}

				@Override
				public Object get(Object key) {
					return null;
				}

				@Override
				public Object put(String key, Object value) {
					return null;
				}

				@Override
				public Object remove(Object key) {
					return null;
				}

				@Override
				public void putAll(Map<? extends String, ?> m) {

				}

				@Override
				public void clear() {

				}

				@Override
				public Set<String> keySet() {
					return null;
				}

				@Override
				public Collection<Object> values() {
					return null;
				}

				@Override
				public Set<Entry<String, Object>> entrySet() {
					return null;
				}
			};
		}
		return Jwts.parser()
				.setSigningKey(SECRET_KEY)
				.parseClaimsJws(token)
				.getBody();
	}


	public static JSONObject getRetuenObj(String token) {
		Claims claims = getClaims(token);
		Object ret = claims.getSubject();
		if(StringUtils.isNotNull(ret)){
			JSONObject obj = JSONObject.parseObject(ret.toString());
			return obj;
		}else {
			return new JSONObject();
		}

	}



}
